﻿using UnityEngine;
using System.Collections;
using UnityEditor.Extension;
using UnityEditor;
using System;
using System.IO;
using UnityEngine.UI;
using System.Reflection.Extension;
using System.Reflection;
using System.Collections.Generic;


[CustomEditor(typeof(ControlBehaviour))]
public class ControlBehaviourInspector : Editor
{
    SerializedProperty control, connections, commands, groups;

    GUIContent emptyContent = new GUIContent("");
    GUILayoutOption width20 = GUILayout.Width(15);
    GUILayoutOption width10 = GUILayout.Width(10);
    [MenuItem("Edit/Clear Catch Folder")]
    private static void NewMenuOption()
    {
        Array.ForEach(Directory.GetFiles(Application.temporaryCachePath),
              delegate (string path) { File.Delete(path); });
    }

    [MenuItem("Edit/Clear Catch")]
    private static void ClearCatch()
    {
        for(int i = 1; i < 5; i++)
        {
            PlayerPrefs.DeleteKey(("Z" + i) + "elapseTime");
            PlayerPrefs.DeleteKey(("Z" + i) + "attempt");
            PlayerPrefs.DeleteKey(("Z" + i) + "locked");
        }
        PlayerPrefs.DeleteKey("HSCloseTime");
        PlayerPrefs.SetString("LiveBanked", "0");
       
    }
    void OnEnable()
    {
        control = serializedObject.FindProperty("control");
        connections = control.FindPropertyRelative("connections");
        commands = serializedObject.FindProperty("commands");
        groups = serializedObject.FindProperty("groups");
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        ControlInspector();
        CommandInspector();
        GroupInspector();
        serializedObject.ApplyModifiedProperties();
    }

    private void ControlInspector()
    {
        connections.ForEachItem("Controls", c =>
        {
            bool canDelete = false;
            SerializedProperty source = c.FindPropertyRelative("source");
            SerializedProperty destination = c.FindPropertyRelative("destination");
            SerializedProperty links = c.FindPropertyRelative("links");
            GUILayout.BeginHorizontal();
            links.isExpanded = GUILayout.Toggle(links.isExpanded, "", EditorStyles.foldout, width20);

            EditorGUILayout.PropertyField(destination, emptyContent);
            GUILayout.Space(10);
            if (GUILayout.Button("+", EditorStyles.miniButtonMid, width20))
                links.AppendItemToArray();
            //GUILayout.Space(5);
            EditorGUILayout.PropertyField(source, emptyContent);
            canDelete = GUILayout.Button("-", EditorStyles.miniButtonRight, width20);
            GUILayout.EndHorizontal();
            if(links.isExpanded)
            links.ForEachItem("", l => {
                bool deleteLink = false;
                SerializedProperty sourcePath = l.FindPropertyRelative("sourcePath");
                SerializedProperty destinationPath = l.FindPropertyRelative("destinationPath");
                SerializedProperty continousUpdate = l.FindPropertyRelative("continousUpdate");
                SerializedProperty localize = l.FindPropertyRelative("localize");
                //SerializedProperty conditionalUpdate = l.FindPropertyRelative("conditionalUpdate");

                GUILayout.BeginHorizontal();
                GUILayout.Label("", width20);   //indent
                continousUpdate.boolValue = GUILayout.Toggle(continousUpdate.boolValue, "", width10);
                EditorGUILayout.PropertyField(destinationPath, emptyContent);

                localize.boolValue = GUILayout.Toggle(localize.boolValue, "", width10);
                EditorGUILayout.PropertyField(sourcePath, emptyContent);
                deleteLink = GUILayout.Button("-", EditorStyles.miniButtonRight, width20);
                GUILayout.EndHorizontal();
                return deleteLink;
            });
            return canDelete;
        });
    }
    private void CommandInspector()
    {
        commands.ForEachItem("Commands", c =>
        {
            bool canDelete = false;
            SerializedProperty source = c.FindPropertyRelative("source");
            SerializedProperty destination = c.FindPropertyRelative("destination");
            SerializedProperty methodPath = c.FindPropertyRelative("methodPath");
            SerializedProperty type = c.FindPropertyRelative("type");
            SerializedProperty parameters = c.FindPropertyRelative("parameters");

            GUILayout.BeginHorizontal();
            parameters.isExpanded = GUILayout.Toggle(parameters.isExpanded, "", EditorStyles.foldout, width20);

            EditorGUILayout.PropertyField(source, emptyContent);
            GUILayout.Label("=>", GUILayout.Width(20));
            EditorGUILayout.PropertyField(destination, emptyContent);
            canDelete = GUILayout.Button("-", EditorStyles.miniButtonRight, width20);
            GUILayout.EndHorizontal();

            if (parameters.isExpanded)
            {
                GUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("", width20);
                EditorGUILayout.PropertyField(type, emptyContent);
                EditorGUILayout.PropertyField(methodPath, emptyContent);
                if (GUILayout.Button(" + ", EditorStyles.miniButtonRight, width20))
                    parameters.AppendItemToArray();
                GUILayout.EndHorizontal();

                parameters.ForEachItem("", p =>
                {
                    bool deleteParameter = false;
                    SerializedProperty objectSource = p.FindPropertyRelative("source");
                    SerializedProperty objectMember = p.FindPropertyRelative("memberPath");

                    GUILayout.BeginHorizontal();
                    GUILayout.Label("", width20);
                    EditorGUILayout.PropertyField(objectSource, emptyContent);
                    EditorGUILayout.PropertyField(objectMember, emptyContent);
                    GUILayout.EndHorizontal();

                    return deleteParameter;
                });
            }
            return canDelete;
        });
    }
    private void GroupInspector()
    {
        groups.ForEachItem("Groups", c =>
        {
            bool canDelete = false;
            SerializedProperty contentPanel = c.FindPropertyRelative("contentPanel");
            SerializedProperty templateCell = c.FindPropertyRelative("templateCell");
            SerializedProperty dataSource = c.FindPropertyRelative("dataSource");
            SerializedProperty enumeratablePath = c.FindPropertyRelative("enumeratablePath");
            SerializedProperty links = c.FindPropertyRelative("links");
            SerializedProperty commandLinks = c.FindPropertyRelative("commandLinks");
            SerializedProperty navigationLink = c.FindPropertyRelative("navigationLink");

            GUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(dataSource, emptyContent);
            GUILayout.Label("->", GUILayout.Width(20));
            EditorGUILayout.PropertyField(enumeratablePath, emptyContent);
            canDelete = canDelete || GUILayout.Button("-", EditorStyles.miniButtonRight, width20);
            GUILayout.EndHorizontal();
            
            GUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(contentPanel, emptyContent);
            GUILayout.Label("*=", GUILayout.Width(20));
            EditorGUILayout.PropertyField(templateCell, emptyContent);
            canDelete = canDelete || GUILayout.Button("-", EditorStyles.miniButtonRight, width20);
            GUILayout.EndHorizontal();

            links.ForEachItemInFold("Links:", l => {
                SerializedProperty sourcePath = l.FindPropertyRelative("sourcePath");
                SerializedProperty destChildPath = l.FindPropertyRelative("destChildPath");
                SerializedProperty destMemberPath = l.FindPropertyRelative("destMemberPath");
                SerializedProperty continousUpdate = l.FindPropertyRelative("continousUpdate");

                EditorGUILayout.PropertyField(destChildPath, emptyContent);
                EditorGUILayout.PropertyField(destMemberPath, emptyContent);
                GUILayout.Label("=", width20);
                EditorGUILayout.PropertyField(continousUpdate, emptyContent, width20);
                EditorGUILayout.PropertyField(sourcePath, emptyContent);
            });

            commandLinks.ForEachItemInFold("Actions:", l =>
            {
                SerializedProperty childPath = l.FindPropertyRelative("childPath");
                SerializedProperty componentPath = l.FindPropertyRelative("componentPath");
                SerializedProperty methodPath = l.FindPropertyRelative("methodPath");

                EditorGUILayout.PropertyField(componentPath, emptyContent);
                GUILayout.Label("=>", GUILayout.Width(20));
                EditorGUILayout.PropertyField(childPath, emptyContent);
                EditorGUILayout.PropertyField(methodPath, emptyContent);
            });

            navigationLink.ForEachItemInFold("Navigation:", l =>
            {
                SerializedProperty childPath = l.FindPropertyRelative("childPath");
                SerializedProperty componentPath = l.FindPropertyRelative("componentPath");
                SerializedProperty conditionPath = l.FindPropertyRelative("conditionPath");
                SerializedProperty toScreen = l.FindPropertyRelative("toScreen");

                EditorGUILayout.PropertyField(childPath, emptyContent);
                EditorGUILayout.PropertyField(componentPath, emptyContent);
                EditorGUILayout.PropertyField(conditionPath, emptyContent);
                GUILayout.Label("->", GUILayout.Width(20));
                EditorGUILayout.PropertyField(toScreen, emptyContent);
            });

            return canDelete;
        });
    }
    /*

    private void ControlsInspector()
    {
        GUILayout.BeginHorizontal();
        controls.isExpanded = GUILayout.Toggle(controls.isExpanded, "Controls", EditorStyles.miniButtonLeft);
        if (GUILayout.Button("+", EditorStyles.miniButtonRight, GUILayout.Width(15)))
            controls.AppendItemToArray();
        GUILayout.EndHorizontal();

        for (int i = 0; i < controls.arraySize; i++)
        {
            SerializedProperty property = controls.GetArrayElementAtIndex(i);
            SerializedProperty sproperty = property.FindPropertyRelative("sourceComponent");
            SerializedProperty dproperty = property.FindPropertyRelative("destinationComponent");
            SerializedProperty sFieldPath = property.FindPropertyRelative("sourcePath");
            SerializedProperty dFieldPath = property.FindPropertyRelative("destinationPath");

            GUILayout.BeginHorizontal();
            EditorGUILayout.PropertyField(dproperty, new GUIContent(""));
            bool addLink = GUILayout.Button("=", EditorStyles.miniButtonMid, GUILayout.Width(15));
            EditorGUILayout.PropertyField(sproperty, new GUIContent(""));

           

           

            if (GUILayout.Button("-", EditorStyles.miniButtonRight, GUILayout.Width(15)))
                controls.DeleteArrayElementAtIndex(i);
            GUILayout.EndHorizontal();

            if (addLink)
            {
                sFieldPath.AppendItemToArray().stringValue = "Select";
                dFieldPath.AppendItemToArray().stringValue = "Select";
            }
            for (int j = 0; j < sFieldPath.arraySize; j++)
            {
                SerializedProperty spath = sFieldPath.GetArrayElementAtIndex(j);
                SerializedProperty dpath = dFieldPath.GetArrayElementAtIndex(j);
                GUILayout.BeginHorizontal();
                if(GUILayout.Button(dpath.stringValue, EditorStyles.miniButtonLeft))
                {
                    GenericMenu menu = new GenericMenu();
                    myTarget.controls[i].destinationComponent.ForEachComponent<Component>(c =>
                    {
                        hitPathField = dpath;
                        c.ForEachMemberInfo((m, path) => menu.AddItem(new GUIContent(c.GetType().Name + "/" + path), false, OnFieldPath, path ));
                    });
                    menu.ShowAsContext();
                }
                GUILayout.Button("=", EditorStyles.miniButtonMid, GUILayout.Width(15));
                if (GUILayout.Button(spath.stringValue, EditorStyles.miniButtonMid))
                {
                    GenericMenu menu = new GenericMenu();
                    myTarget.controls[i].sourceComponent.ForEachComponent<Component>(c =>
                    {
                        hitPathField = spath;
                        c.ForEachMemberInfo((m, path) => menu.AddItem(new GUIContent(c.GetType().Name + "/" + path), false, OnFieldPath, path));
                    });
                    menu.ShowAsContext();
                }

                if (GUILayout.Button("-", EditorStyles.miniButtonRight, GUILayout.Width(15)))
                { sFieldPath.DeleteArrayElementAtIndex(j); sFieldPath.DeleteArrayElementAtIndex(j); }
                GUILayout.EndHorizontal();
            }
            GUILayout.Space(10);
        }
    }
    SerializedProperty hitPathField;
    void OnFieldPath(object obj)
    {
        serializedObject.Update();
        hitPathField.stringValue = (string)obj;
        serializedObject.ApplyModifiedProperties();
    }
    */
}